<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "DTD/xhtml1-transitional.dtd">















 
 
 
 
 
 
 
  
  


<html>
  <head>
    <script type="text/javascript" language="JavaScript">
    ORIGINAL_PAGE_PATH = "/appengine/docs/java/datastore/transactions.html";
    </script>
    
    
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Transactions - Google App Engine - Google Code</title>
<script type="text/javascript"><!--
(function(){function a(){this.t={};this.tick=function(c){this.t[c]=(new Date).getTime()};this.tick("start")}var b=new a;window.jstiming={Timer:a,load:b};if(window.external&&window.external.pageT)window.jstiming.pt=window.external.pageT;})();

var _tocPath_ = '/appengine/docs/_toc.ezt';
var codesite_token = null;
//--></script>
<link href="../../../../css/codesite.pack.04102009.css" type="text/css" rel="stylesheet"></link>
<script src="../../../../js/codesite_head.pack.04102009.js" type="text/javascript"></script>
<script type="text/javascript">CODESITE_CSITimer['load'].tick('bhs');</script>
<link rel="search" type="application/opensearchdescription+xml" title="Google Code" href="http://code.google.com/osd.xml" />

<!--[if IE]><link rel="stylesheet" type="text/css" href="../../../../css/iehacks.css" /><![endif]-->

    <link href="../../../../css/semantic_headers.css" rel="stylesheet" type="text/css" />
    <link href="../../../css/local_extensions.css" rel="stylesheet" type="text/css" />
  </head>

  <body class="gc-documentation">

    
    
    
</a>

<div id="gb">
 <span>
  
    <a id="lang-dropdown" class="dropdown" href="http://code.google.com" onclick="return false;"><img class="globeicon" src="../../../../images/globe2_small.png"/><span>English</span></a>
  
 </span>
</div>

<div class="gbh" style="left: 0pt;"></div>
<div class="gbh" style="right: 0pt;"></div>


<style type="text/css">
  #gc-topnav h1 {
    padding: 0 0 0 6px;
  }
</style>


<div id="gc-container">
<a name="top"></a>
<div id="skipto">
  <a href="#gc-pagecontent">Skip to page content</a>
  <a href="#gc-toc">Skip to main navigation</a>
</div>

<div id="gc-header">
  <div id="logo"><a href="http://code.google.com">
  
  
     <img src="../../../../images/cleardot.gif" height="1px" width="1px" alt="Google Code Home Page" id="gc-logo-img"/>
  
  
  </a></div>
  <div id="search">
    <div id="searchForm" class="searchForm">
      <form id="cse" action="http://www.google.com/cse" accept-charset="utf-8" class="gsc-search-box" onsubmit="executeGSearch(document.getElementById('gsearchInput').value); return false;">
      <noscript>
      <input type="hidden" name="cref" value="http://code.google.com/cse/googlecode-context.xml"/>
      </noscript>
        <table class="gsc-search-box" cellpadding="0" cellspacing="0">
          <tbody>
            <tr>
              <td class="gsc-input">
                <input id="gsearchInput" type="text" name="q" maxlength="2048" class="gsc-input" autocomplete="off" title="Google Code Search" style="width:345px"/>
              </td>
              <td class="gsc-search-button">
                <div id="cs-searchresults" onclick="event.cancelBubble = true;"></div>
                <input title="Search" id="gsearchButton" class="gsc-search-button" name="sa" value="Search" type="submit"/>
              </td>
            </tr>
            <tr>
              <td colspan="2" class="greytext">e.g. "templates" or "datastore"</td>
            </tr>
          </tbody>
        </table>
      </form>
    </div> <!-- end searchForm -->
  </div> <!-- end search -->
</div> <!-- end gc-header -->


<div id="codesiteContent">

<a name="gc-topnav-anchor"></a>
<div id="gc-topnav">
  <h1>Google App Engine</h1>
  <ul id="docs" class="gc-topnav-tabs">

    <li id="home_link">
      <a href="../../../index.html" title="Google App Engine home page">Home</a>
    </li>
  
    <li id="docs_link">
      <a href="../../index.html" class="selected" title="Official Google App Engine documentation">Docs</a>
    </li>
  
    <li id="faq_link">
      <a href="../../../kb/index.html" title="Answers to frequently asked questions about Google App Engine">FAQ</a>
    </li>
  
    <li id="articles_link">
      <a href="../../../articles/index.html" title="Focused articles and tutorials for Google App Engine developers">Articles</a>
    </li>
  
    <li>
      <a href="http://googleappengine.blogspot.com/" title="Official Google App Engine blog">Blog</a>
    </li>
  
    <li>
      <a href="../../../community.html" title="Community home for Google App Engine">Community</a>
    </li>
  
    <li>
      <a href="../../../terms.html" title="Google App Engine terms of service">Terms</a>
    </li>
  
    <li>
      <a href="../../../downloads.html" title="Download Google App Engine">Download</a>
    </li>
  

  </ul>
</div> <!-- end gc-topnav -->

    <div class="g-section g-tpl-170">

      <div class="g-unit g-first" id="gc-toc">
        <ul>
  <li><a href="../../../downloads.html">Downloads</a></li>
  <li><a href="http://code.google.com/status/appengine">System Status</a></li>
  <li><a href="http://code.google.com/p/googleappengine/issues/list">Issue Tracker</a></li>
</ul>
<div class="line"></div>
<ul>
  <li><h2>Getting Started</h2>
    <ul>
      <li><a href="../../whatisgoogleappengine.html">What Is Google App Engine?</a></li>
      <li><a href="../gettingstarted/index.html">Java</a>
        <ul>
              <li><a href="../gettingstarted/introduction.html">Introduction</a></li>
    <li><a href="../gettingstarted/installing.html">Installing the Java SDK</a></li>
    <li><a href="../gettingstarted/creating.html">Creating a Project</a></li>
    <li><a href="../gettingstarted/usingusers.html">Using the Users Service</a></li>
    <li><a href="../gettingstarted/usingjsps.html">Using JSPs</a></li>
    <li><a href="../gettingstarted/usingdatastore.html">Using the Datastore with JDO</a></li>
    <li><a href="../gettingstarted/staticfiles.html">Using Static Files</a></li>
    <li><a href="../gettingstarted/uploading.html">Uploading Your Application</a></li>

        </ul>
      </li>
      <li><a href="../../python/gettingstarted/index.html">Python</a>
        <ul>
            <li><a href="../../python/gettingstarted/introduction.html">Introduction</a></li>
  <li><a href="../../python/gettingstarted/devenvironment.html">The Development Environment</a></li>
  <li><a href="../../python/gettingstarted/helloworld.html">Hello, World!</a></li>
  <li><a href="../../python/gettingstarted/usingwebapp.html">Using the webapp Framework</a></li>
  <li><a href="../../python/gettingstarted/usingusers.html">Using the Users Service</a></li>
  <li><a href="../../python/gettingstarted/handlingforms.html">Handling Forms With webapp</a></li>
  <li><a href="../../python/gettingstarted/usingdatastore.html">Using the Datastore</a></li>
  <li><a href="../../python/gettingstarted/templates.html">Using Templates</a></li>
  <li><a href="../../python/gettingstarted/staticfiles.html">Using Static Files</a></li>
  <li><a href="../../python/gettingstarted/uploading.html">Uploading Your Application</a></li>

        </ul>
      </li>
    </ul>
  </li>
</ul>
<div class="line"></div>
<ul>
  <li><h2>Java <sup class="new">Early Look</sup></h2>
    <ul>
          <li><a href="../overview.html">Overview</a></li>
    <li><a href="../runtime.html">Servlet Environment</a></li>
    <li><a href="index.html">Storing Data</a>
      <ul>
            <li><a href="overview.html">Overview</a></li>
    <li><a href="usingjdo.html">Using JDO</a></li>
    <li><a href="dataclasses.html">Defining Data Classes</a></li>
    <li><a href="creatinggettinganddeletingdata.html">Creating, Getting and Deleting Data</a></li>
    <li><a href="queriesandindexes.html">Queries and Indexes</a></li>
    <li><a href="transactions.html">Transactions</a></li>
    <li><a href="relationships.html">Relationships</a></li>
    <li><a href="usingjpa.html">Using JPA</a></li>
    <li><a href="../javadoc/com/google/appengine/api/datastore/package-summary.html">Low-level API</a></li>

      </ul>
    </li>
    <li><a href="../apis.html">Services</a>
      <ul>
        <li><a href="../memcache/index.html">Memcache</a>
          <ul>
                <li><a href="../memcache/overview.html">Overview</a></li>
    <li><a href="../memcache/usingjcache.html">Using JCache</a></li>
    <li><a href="../javadoc/com/google/appengine/api/memcache/package-summary.html">Low-level API</a></li>

          </ul>
        </li>
        <li><a href="../urlfetch/index.html">URL Fetch</a>
          <ul>
                <li><a href="../urlfetch/overview.html">Overview</a></li>
    <li><a href="../urlfetch/usingjavanet.html">Using java.net</a></li>
    <li><a href="../javadoc/com/google/appengine/api/urlfetch/package-summary.html">Low-level API</a></li>

          </ul>
        </li>
        <li><a href="../mail/index.html">Mail</a>
          <ul>
                <li><a href="../mail/overview.html">Overview</a></li>
    <li><a href="../mail/usingjavamail.html">Using JavaMail</a></li>
    <li><a href="../javadoc/com/google/appengine/api/mail/package-summary.html">Low-level API</a></li>

          </ul>
        </li>
        <li><a href="../images/index.html">Images</a>
          <ul>
                <li><a href="../images/overview.html">Overview</a></li>
    <li><a href="../javadoc/com/google/appengine/api/images/package-summary.html">API Reference</a></li>

          </ul>
        </li>
        <li><a href="../users/index.html">Google Accounts</a>
          <ul>
                <li><a href="../users/overview.html">Overview</a></li>
    <li><a href="../javadoc/com/google/appengine/api/users/package-summary.html">API Reference</a></li>

          </ul>
        </li>
      </ul>
    </li>
    <li><a href="../javadoc/index.html">Javadoc Reference</a></li>
    <li><a href="../jrewhitelist.html">JRE Class White List</a></li>
    <li><a href="../config/index.html">Configuration</a>
      <ul>
            <li><a href="../config/webxml.html">Deployment Descriptor</a></li>
    <li><a href="../config/appconfig.html">App Config</a></li>
    <li><a href="../config/indexconfig.html">Index Config</a></li>
    <li><a href="../config/cron.html">Scheduled Tasks</a></li>

      </ul>
    </li>
    <li><a href="../tools/index.html">Tools</a>
      <ul>
            <li><a href="../tools/devserver.html">Development Server</a></li>
    <li><a href="../tools/uploadinganapp.html">Uploading and Managing</a></li>
    <li><a href="../tools/eclipse.html">Google Plugin for Eclipse</a></li>
    <li><a href="../tools/ant.html">Using Apache Ant</a></li>

      </ul>
    </li>
    <li><a href="../howto/index.html">How-To</a>
      <ul>
              <li><a href="../howto/unittesting.html">Unit Testing</a></li>

      </ul>
    </li>

    </ul>
  </li>
</ul>
<div class="line"></div>
<ul>
  <li><h2>Python</h2>
    <ul>
          <li><a href="../../python/overview.html">Overview</a></li>
    <li><a href="../../python/runtime.html">CGI Environment</a></li>
    <li><a href="../../python/datastore/index.html">Storing Data</a>
      <ul>
             <li><a href="../../python/datastore/overview.html">Overview</a></li>
     <li><a href="../../python/datastore/entitiesandmodels.html">Entities and Models</a></li>
     <li><a href="../../python/datastore/creatinggettinganddeletingdata.html">Creating, Getting and Deleting Data</a></li>
     <li><a href="../../python/datastore/keysandentitygroups.html">Keys and Entity Groups</a></li>
     <li><a href="../../python/datastore/queriesandindexes.html">Queries and Indexes</a></li>
     <li><a href="../../python/datastore/transactions.html">Transactions</a></li>
     <li><a href="../../python/datastore/typesandpropertyclasses.html">Types and Property Classes</a></li>
     <li><a href="../../python/datastore/gqlreference.html">GQL Reference</a></li>

     <li><span class="tlw-title tlw-expanded">Reference</span>
       <ul>
         <li><a href="../../python/datastore/modelclass.html">Model</a></li>
         <li><a href="../../python/datastore/expandoclass.html">Expando</a></li>
         <li><a href="../../python/datastore/polymodelclass.html">PolyModel</a></li>
         <li><a href="../../python/datastore/propertyclass.html">Property</a></li>
         <li><a href="../../python/datastore/queryclass.html">Query</a></li>
         <li><a href="../../python/datastore/gqlqueryclass.html">GqlQuery</a></li>
         <li><a href="../../python/datastore/keyclass.html">Key</a></li>
         <li><a href="../../python/datastore/functions.html">Functions</a></li>
         <li><a href="../../python/datastore/exceptions.html">Exceptions</a></li>
       </ul>
     </li>

      </ul>
    </li>
    <li><a href="../../python/apis.html">Services</a>
      <ul>
        <li><a href="../../python/memcache/index.html">Memcache</a>
          <ul>
                 <li><a href="../../python/memcache/overview.html">Overview</a></li>
      <li><a href="../../python/memcache/usingmemcache.html">Using Memcache</a></li>
     <li><span class="tlw-title tlw-expanded">Reference</span>
       <ul>
         <li><a href="../../python/memcache/clientclass.html">Client</a></li>
         <li><a href="../../python/memcache/functions.html">Functions</a></li>
       </ul>
     </li>

          </ul>
        </li>
        <li><a href="../../python/urlfetch/index.html">URL Fetch</a>
          <ul>
                 <li><a href="../../python/urlfetch/overview.html">Overview</a></li>
     <li><span class="tlw-title tlw-expanded">Reference</span>
       <ul>
         <li><a href="../../python/urlfetch/fetchfunction.html">The fetch Function</a></li>
         <li><a href="../../python/urlfetch/responseobjects.html">Response Objects</a></li>
         <li><a href="../../python/urlfetch/exceptions.html">Exceptions</a></li>
       </ul>
     </li>

          </ul>
        </li>
        <li><a href="../../python/mail/index.html">Mail</a>
          <ul>
                 <li><a href="../../python/mail/overview.html">Overview</a></li>
     <li><a href="../../python/mail/sendingmail.html">Sending Mail</a></li>
     <li><a href="../../python/mail/attachments.html">Attachments</a></li>
     <li><span class="tlw-title tlw-expanded">Reference</span>
       <ul>
         <li><a href="../../python/mail/emailmessageclass.html">EmailMessage</a></li>
         <li><a href="../../python/mail/emailmessagefields.html">Message Fields</a></li>
         <li><a href="../../python/mail/functions.html">Functions</a></li>
         <li><a href="../../python/mail/exceptions.html">Exceptions</a></li>
       </ul>
     </li>

          </ul>
        </li>
        <li><a href="../../python/images/index.html">Images</a>
          <ul>
                 <li><a href="../../python/images/overview.html">Overview</a></li>
     <li><a href="../../python/images/installingPIL.html">Installing PIL</a></li>
     <li><a href="../../python/images/usingimages.html">Using the Images API</a></li>
     <li><span class="tlw-title tlw-expanded">Reference</span>
       <ul>
         <li><a href="../../python/images/imageclass.html">Image</a></li>
         <li><a href="../../python/images/functions.html">Functions</a></li>
         <li><a href="../../python/images/exceptions.html">Exceptions</a></li>
       </ul>
     </li>

          </ul>
        </li>
        <li><a href="../../python/users/index.html">Google Accounts</a>
          <ul>
                 <li><a href="../../python/users/overview.html">Overview</a></li>
     <li><a href="../../python/users/userobjects.html">User Objects</a></li>
     <li><a href="../../python/users/loginurls.html">Login URLs</a></li>
     <li><a href="../../python/users/adminusers.html">Admin Users</a></li>

     <li><span class="tlw-title tlw-expanded">Reference</span>
       <ul>
         <li><a href="../../python/users/userclass.html">User</a></li>
         <li><a href="../../python/users/functions.html">Functions</a></li>
         <li><a href="../../python/users/exceptions.html">Exceptions</a></li>
       </ul>
     </li>

          </ul>
        </li>
      </ul>
    </li>
    <li><a href="../../python/config/index.html">Configuration</a>
      <ul>
            <li><a href="../../python/config/appconfig.html">App Config</a></li>
    <li><a href="../../python/config/indexconfig.html">Index Config</a></li>
    <li><a href="../../python/config/cron.html">Scheduled Tasks</a></li>

      </ul>
    </li>
    <li><a href="../../python/tools/index.html">Tools</a>
      <ul>
            <li><a href="../../python/tools/devserver.html">Development Server</a></li>
    <li><a href="../../python/tools/uploadinganapp.html">Uploading and Managing</a></li>
    <li><a href="../../python/tools/uploadingdata.html">Uploading Data</a></li>
    <li><a href="../../python/tools/webapp/index.html">webapp Framework</a>
      <ul>
             <li><a href="../../python/tools/webapp/overview.html">Overview</a></li>
     <li><a href="../../python/tools/webapp/running.html">Running the Application</a></li>
     <li><a href="../../python/tools/webapp/requesthandlers.html">Request Handlers</a></li>
     <li><a href="../../python/tools/webapp/requestdata.html">Request Data</a></li>
     <li><a href="../../python/tools/webapp/buildingtheresponse.html">Building the Response</a></li>
     <li><a href="../../python/tools/webapp/redirects.html">Redirects, Headers and Status Codes</a></li>
     

     <li><span class="tlw-title tlw-expanded">Reference</span>
       <ul>
         <li><a href="../../python/tools/webapp/requestclass.html">Request</a></li>
         <li><a href="../../python/tools/webapp/responseclass.html">Response</a></li>
         <li><a href="../../python/tools/webapp/requesthandlerclass.html">RequestHandler</a></li>
         <li><a href="../../python/tools/webapp/wsgiapplicationclass.html">WSGIApplication</a></li>
         <li><a href="../../python/tools/webapp/utilmodule.html">Utility Functions</a></li>
         
       </ul>
     </li>

      </ul>
    </li>
    <li><a href="../../python/tools/libraries.html">Third-party Libraries</a></li>

      </ul>
    </li>
    <li><a href="../../python/howto/index.html">How-To</a>
      <ul>
              <li><a href="../../python/howto/usinggdataservices.html">Google Data Services</a></li>

      </ul>
    </li>

    </ul>
  </li>
</ul>
<div class="line"></div>
<ul>
  <li><h2>Managing Your App</h2>
    <ul>
      <li><a href="../../theadminconsole.html">The Admin Console</a></li>
      <li><a href="../../quotas.html">Quotas</a></li>
      <li><a href="../../billing.html">Billing</a></li>
    </ul>
  </li>
</ul>
<div class="line"></div>
<ul>
  <li><h2>Resources</h2>
    <ul>
      <li><a href="../../../kb/index.html">FAQ</a></li>
      <li><a href="../../../articles/index.html">Articles</a></li>
      <li><a href="http://appengine-cookbook.appspot.com/">Cookbook</a></li>
      <li><a href="http://appgallery.appspot.com/">App Gallery</a></li>
      <li><a href="http://code.google.com/p/googleappengine/">SDK Code</a></li>
      <li><a href="http://code.google.com/p/google-app-engine-samples/">Sample Apps Code</a></li>
      <li><a href="../../../community.html">Discussion Groups</a></li>
    </ul>
  </li>
</ul>
<div class="line"></div>
<ul>
  <li><a href="../../roadmap.html">Product Roadmap</a></li>
  <li><a href="http://code.google.com/p/googleappengine/wiki/SdkReleaseNotes">Release Notes</a></li>
  <li><a href="../../revision_history.html">Revision History</a></li>
</ul>

        <a class="hidden" href="#gc-topnav-anchor">More Google App Engine resource links</a>
      </div>

      <div class="g-unit" id="gc-pagecontent">
        <h1 class="page_title">Transactions</h1>












<p>The App Engine datastore supports <i>transactions</i>.  A transaction is an operation or set of operations that either succeeds completely, or fails completely.  An application can perform multiple operations and calculations in a single transaction.</p>

<ul>
  <li><a href="#Using_Transactions">Using Transactions</a></li>
  <li><a href="#What_Can_Be_Done_In_a_Transaction">What Can Be Done In a Transaction</a></li>
  <li><a href="#Uses_For_Transactions">Uses For Transactions</a></li>

  <li><a href="#Disabling_Transactions_and_Porting_Existing_JDO_Apps">Disabling Transactions and Porting Existing JDO Apps</a></li>

</ul>

<h2 id="Using_Transactions">Using Transactions</h2>

<p>A <i>transaction</i> is a datastore operation or a set of datastore operations that either succeed completely, or fail completely.  If the transaction succeeds, then all of its intended effects are applied to the datastore.  If the transaction fails, then none of the effects are applied.</p>

<p>Every datastore write operation is atomic.  An attempt to create, update or delete an entity either happens, or it doesn't.  An operation may fail due to a high rate of contention, with too many users trying to modify an entity at the same time.  Or an operation may fail due to the application reaching a quota limit.  Or there may be an internal error with the datastore.  In all cases, the operation's effects are not applied, and the datastore API raises an exception.</p>


<p>Here is an example of incrementing a field named <code>counter</code> in an object named <code>ClubMembers</code> (class not shown) using the JDO transaction API:</p>

<pre class="prettyprint">
import javax.jdo.Transaction;

import ClubMembers;   // not shown

// ...
        // PersistenceManager pm = ...;

        Transaction tx = pm.currentTransaction();

        try {
            tx.begin();
    
            ClubMembers members = pm.getObjectById(ClubMembers.class, "k12345");
            members.incrementCounterBy(1);
            pm.makePersistent(members);
    
            tx.commit();
        } finally {
            if (tx.isActive()) {
                tx.rollback();
            }
        }
</pre>


<h3>Entity Groups</h3>

<p>Every entity belongs to an <i>entity group</i>, a set of one or more entities that can be manipulated in a single transaction.  Entity group relationships tell App Engine to store several entities in the same part of the distributed network.  A transaction sets up datastore operations for an entity group, and all of the operations are applied as a group, or not at all if the transaction fails.</p>

<p>When the application creates an entity, it can assign another entity as the <i>parent</i> of the new entity.  Assigning a parent to a new entity puts the new entity in the same entity group as the parent entity.</p>

<p>An entity without a parent is a <i>root</i> entity.  An entity that is a parent for another entity can also have a parent.  A chain of parent entities from an entity up to the root is the <i>path</i> for the entity, and members of the path are the entity's <i>ancestors</i>.  The parent of an entity is defined when the entity is created, and cannot be changed later.</p>

<p>Every entity with a given root entity as an ancestor is in the same entity group.  All entities in a group are stored in the same datastore node.  A single transaction can modify multiple entities in a single group, or add new entities to the group by making the new entity's parent an existing entity in the group.</p>




<h3>Creating Entities With Entity Groups</h3>

<p>The App Engine implementation of the JDO interface represents owned one-to-one or one-to-many relationships using entity groups.  This allows changes to an object and changes to its child objects to occur in the same transaction.  See <a href="relationships.html">Relationships</a>.</p>

<p>For other situations, you can create an entity with an explicit entity group parent by setting the object's primary key field to the complete key, including the parent's key.  The object's primary key field must be either a Key instance or an encoded key string (not a simple Long or String key name).</p>

<p>When using app-assigned string IDs, you can create an object with an entity group parent by setting its key field to the complete key value, which includes the key of the parent.  To create a key value using an entity group parent, use the KeyFactory.Builder class, as follows:</p>

<pre class="prettyprint">
import javax.jdo.annotations.IdentityType;
import javax.jdo.annotations.IdGeneratorStrategy;
import javax.jdo.annotations.PersistenceCapable;
import javax.jdo.annotations.Persistent;
import javax.jdo.annotations.PrimaryKey;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;

@PersistenceCapable(identityType = IdentityType.APPLICATION)
public class AccountInfo {
    @PrimaryKey
    @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY)
    private Key key;

    public void setKey(Key key) {
        this.key = key;
    }
}

// ...
        KeyFactory.Builder keyBuilder = new KeyFactory.Builder(Customer.class.getSimpleName(), "custid985135");
        keyBuilder.addChild(AccountInfo.class.getSimpleName(), "acctidX142516");
        Key key = keyBuilder.getKey();

        AccountInfo acct = new AccountInfo();
        acct.setKey(key);
        pm.makePersistent(acct);
</pre>

<p>You can access the entity group parent key separately from the object's key using a field, as follows:</p>

<pre class="prettyprint">
// ...
    @Persistent
    @Extension(vendorName="datanucleus", key="gae.parent-pk", value="true")
    private Key customerKey;
</pre>

<p>To create an object with a system-generated numeric ID and an entity group parent, you must use an entity group parent key field (such as <code>customerKey</code>, above).  Assign the key of the parent to the parent key field, then leave the object's key field set to null.  When the object is saved, the datastore populates the key field with the complete key, including the entity group parent.</p>

<p>If a class has an entity group parent field, you can use an equality filter in a query on the parent field. (Inequality filters on parent keys are not supported.)</p>




<h2 id="What_Can_Be_Done_In_a_Transaction">What Can Be Done In a Transaction</h2>

<p>The datastore imposes several restrictions on what can be done inside a single transaction.</p>

<p>All datastore operations in a transaction must operate on entities in the same entity group.  This includes retrieving entities by key, updating entities, and deleting entities.  Notice that each root entity belongs to a separate entity group, so a single transaction cannot create or operate on more than one root entity.  </p>

<p>An app cannot perform a query during a transaction.  However, an app can retrieve datastore entities using keys during a transaction, and be guaranteed that the fetched entity is consistent with the rest of the transaction.  You can prepare keys prior to the transaction, or you can build keys inside the transaction with key names or IDs.</p>

<p>An application cannot create or update an entity more than once in a single transaction.</p>


<p>JDO performs all actions between the call to <code>tx.begin()</code> and the call to <code>tx.commit()</code> in a single transaction.  If any action fails due to the requested entity group being in use by another process, JDO throws a JDODataStoreException or a JDOException, cause by a java.util.ConcurrentModificationException.</p>

<p>In a system with optimistic concurrency, it is typical for an application to try the transaction again several times before giving up.  JDO only performs the transaction once; the application must repeat the transaction, if desired.  For example:</p>

<pre class="prettyprint">
        for (int i = 0; i < NUM_RETRIES; i++) {
            pm.currentTransaction().begin();

            ClubMembers members = pm.getObjectById(ClubMembers.class, "k12345");
            members.incrementCounterBy(1);

            try {
                pm.currentTransaction().commit();
                break;

            } catch (JDOCanRetryException ex) {
                if (i == (NUM_RETRIES - 1)) { 
                    throw ex;
                }
            }
        }
</pre>

<p>An attempt to update more than one entity group in the same transaction will throw a JDOFatalUserException.  Notice that each object that doesn't have an entity group parent resides in its own entity group, so you cannot create multiple parent-less entities in a single transaction.</p>

<p>An attempt to update the same entity multiple times in a single transaction (such as with repeated <code>makePersistent()</code> calls) will throw a JDOFatalUserException.  Instead, just modify the persistent objects within the transaction, and allow the call to <code>commit()</code> to apply the changes.</p>



<h2 id="Uses_For_Transactions">Uses For Transactions</h2>

<p>This example demonstrates one use of transactions: updating an entity with a new property value relative to its current value.</p>



<pre class="prettyprint">
        Key k = KeyFactory.createKey("Employee", "k12345");
        Employee e = pm.getObjectById(Employee.class, k);
        e.counter += 1;
        pm.makePersistent(e);
</pre>


<p>This requires a transaction because the value may be updated by another user after this code fetches the object, but before it saves the modified object.  Without a transaction, the user's request will use the value of <code>counter</code> prior to the other user's update, and the save will overwrite the new value.  With a transaction, the application is told about the other user's update.  If the entity is updated during the transaction, then the transaction fails with an exception.  The application can repeat the transaction to use the new data.</p>

<p>Another common use for transactions is to update an entity with a named key, or create it if it doesn't yet exist:</p>



<pre class="prettyprint">
        // PersistenceManager pm = ...;

        Transaction tx = pm.currentTransaction();

        String id = "jj_industrial";
        String companyName = "J.J. Industrial";
       
        try {
            tx.begin();

            Key k = KeyFactory.createKey("SalesAccount", id);
            SalesAccount account;
            try {
                account = pm.getObjectById(Employee.class, k);
            } catch (JDOObjectNotFoundException e) {
                account = new SalesAccount();
                account.setId(id);
            }

            account.setCompanyName(companyName);
            pm.makePersistent(account);

            tx.commit();

        } finally {
            if (tx.isActive()) {
                tx.rollback();
            }
        }
</pre>


<p>As before, a transaction is necessary to handle the case where another user is attempting to create or update an entity with the same string ID.  Without a transaction, if the entity does not exist and two users attempt to create it, the second will overwrite the first without knowing that it happened.  With a transaction, the second attempt will fail atomically, and can be retried by the application to fetch the new entity and update it.</p>



<p class="note"><b>Tip:</b> A transaction should happen as quickly as possible to reduce the likelihood that the entities used by the transaction will change, requiring the transaction be retried.  As much as possible, prepare data outside of the transaction, then execute the transaction to perform datastore operations that depend on a consistent state.  The application should prepare keys for objects used inside the transaction, then fetch the entities inside the transaction.</p>


<h2 id="Disabling_Transactions_and_Porting_Existing_JDO_Apps">Disabling Transactions and Porting Existing JDO Apps</h2>
<p>The JDO configuration we recommend using sets a property named <code>datanucleus.appengine.autoCreateDatastoreTxns</code> to <code>true</code>.  This is an App Engine-specific property that tells the JDO implementation to associate datastore transactions with the JDO transactions that are managed in application code.  If you are building a new app from scratch, this is probably what you want.  However, if you have an existing, JDO-based application that you want to get running on App Engine, you may want to use an alternate persistence configuration which sets the value of this property to <code>false</code>:</p>
<pre>
&lt;?xml version="1.0" encoding="utf-8"?&gt;
&lt;jdoconfig xmlns="http://java.sun.com/xml/ns/jdo/jdoconfig"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="http://java.sun.com/xml/ns/jdo/jdoconfig"&gt;

    &lt;persistence-manager-factory name="transactions-optional"&gt;
        &lt;property name="javax.jdo.PersistenceManagerFactoryClass"
            value="org.datanucleus.store.appengine.jdo.DatastoreJDOPersistenceManagerFactory"/&gt;
        &lt;property name="javax.jdo.option.ConnectionURL" value="appengine"/&gt;
        &lt;property name="javax.jdo.option.NontransactionalRead" value="true"/&gt;
        &lt;property name="javax.jdo.option.NontransactionalWrite" value="true"/&gt;
        &lt;property name="javax.jdo.option.RetainValues" value="true"/&gt;
        &lt;property name="datanucleus.appengine.autoCreateDatastoreTxns" value="false"/&gt;
    &lt;/persistence-manager-factory&gt;
&lt;/jdoconfig&gt;
</pre>
<p>In order to understand why this may be useful, remember that you can only operate on objects that belong to the same entity group within a transaction.  Applications built using traditional databases typically assume the availability of global transactions, which allow you to update any set of records inside a transaction.  Since the App Engine datastore does not support global transactions, code that assumes the availability of global transactions will yield exceptions.  Instead of going through your (potentially large) codebase and removing all your transaction management code, you can simply disable datastore transactions.  This of course does nothing to address assumptions your code makes about atomicity of multi-record modifications, but it allows you to get your app working so that you can then focus on refactoring your transactional code incrementally and as needed, rather than all at once.</p>




      </div><!-- end gc-pagecontent -->
   </div><!-- end gooey wrapper -->

    </div> <!-- end codesite content -->

<div id="gc-footer" dir="ltr">
  <div class="text">
    
      <div class="notice"><div id="notice" style="text-align: center; border: 1em 0em 1em 0em">
  Except as otherwise <a
  href="http://code.google.com/policies.html#restrictions">noted</a>,
  the content of this page is licensed under the <a rel="license"
  href="http://creativecommons.org/licenses/by/2.5/">Creative Commons
  Attribution 2.5 License</a>, and code samples are licensed under the
  <a rel="license" href="http://www.apache.org/licenses/LICENSE-2.0">Apache
  2.0 License</a>.
<!-- <rdf:RDF xmlns="http://web.resource.org/cc/" 
              xmlns:dc="http://purl.org/dc/elements/1.1/"
              xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
  <Work rdf:about="">
    <license rdf:resource="http://creativecommons.org/licenses/by/2.5/" />
  </Work>
  <License rdf:about="http://creativecommons.org/licenses/by/2.5/">
    <permits rdf:resource="http://web.resource.org/cc/Reproduction"/>
    <permits rdf:resource="http://web.resource.org/cc/Distribution"/>
    <requires rdf:resource="http://web.resource.org/cc/Notice"/>
    <requires rdf:resource="http://web.resource.org/cc/Attribution"/>
    <permits rdf:resource="http://web.resource.org/cc/DerivativeWorks"/>
  </License>
</rdf:RDF> -->
</div>
Java is a registered trademark of Sun Microsystems, Inc.</div>
    
    &copy;2009 Google -
    <a href="http://code.google.com">Code Home</a> -
    <a href="http://www.google.com/accounts/TOS">Terms of Service</a> -
    <a href="http://www.google.com/privacy.html">Privacy Policy</a> -
    <a href="http://code.google.com/more">Site Directory</a>
    <br /> <br />
    Google Code offered in:
    <a href="http://code.google.com/intl/en">English</a> -
    <a href="http://code.google.com/intl/es">Español</a> -
    <a href="http://code.google.com/intl/ja">日本語</a> -
    <a href="http://code.google.com/intl/ko">한국어</a> -
    <a href="http://code.google.com/intl/pt-BR">Português</a> -
    <a href="http://code.google.com/intl/ru">Pусский</a> -
    <a href="http://code.google.com/intl/zh-CN">中文(简体)</a> -
    <a href="http://code.google.com/intl/zh-TW">中文(繁體)</a>
  </div>
</div><!-- end gc-footer -->

</div><!-- end gc-containter -->

<script type="text/javascript">CODESITE_CSITimer['load'].tick('ats');</script>
<script src="../../../../js/codesite_tail.pack.04102009.js" type="text/javascript"></script>






  </body>
</html>


